package com.joymart.manual.operation.log.service;

import com.joymart.common.model.Range;
import com.joymart.common.system.IdGenerator;
import com.joymart.common.utils.DatetimeUtils;
import com.joymart.manual.operation.log.model.ManualOperationLog;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static com.joymart.common.utils.CollectionUtils.asList;
import static org.springframework.data.relational.core.query.Criteria.where;
import static org.springframework.data.relational.core.query.Query.query;


@Service
public class ManualOperationLogService {

    @Autowired
    private IdGenerator idGenerator;
    @Autowired
    private JdbcAggregateTemplate jdbcAggregateTemplate;

    public ManualOperationLog insert(String type, String subjectId, Map<String, Object> details, String operatorId) {
        ManualOperationLog log = new ManualOperationLog();
        log.setId(idGenerator.next());
        log.setSubjectId(subjectId);
        log.setType(type);
        log.setDetails(new JSONObject(details));
        log.setOperatorId(operatorId);
        log.setCreatedAt(DatetimeUtils.now());
        jdbcAggregateTemplate.insert(log);
        return log;
    }


    public Page<ManualOperationLog> search(Pageable pageable,
                                           Range range,
                                           String type,
                                           String subjectId,
                                           String operatorId) {
        LocalDateTime start = range.getStart();
        LocalDateTime end = range.getEnd();
        Criteria criteria = where("createdAt").between(start, end);

        if (StringUtils.hasText(subjectId)) {
            criteria = criteria.and(where("subjectId").is(subjectId));
        }

        if (StringUtils.hasText(operatorId)) {
            criteria = criteria.and(where("operatorId").is(operatorId));
        }

        if (StringUtils.hasText(type)) {
            criteria = criteria.and(where("type").is(type));
        }

        long count = jdbcAggregateTemplate.count(query(criteria), ManualOperationLog.class);
        if (count == 0) {
            return Page.empty();
        } else {
            List<ManualOperationLog> content = asList(jdbcAggregateTemplate.findAll(query(criteria).limit(pageable.getPageSize()).offset(pageable.getOffset())
                    .sort(Sort.by(Sort.Direction.DESC, "createdAt")), ManualOperationLog.class));
            return new PageImpl<>(content, pageable, count);
        }

    }


}
